/**
 * 文件名称:  TBcUserServiceImpl.java
 * 文件序号:  序号
 * 内容描述:  用户管理service层接口实现类
 * 版权声明:  山东鸿蝶信息技术有限公司
 * 创建用户:  MissJin
 * 创建日期:  2017/1/17/11:29
 * 修改用户:  无
 * 修改日期:  无
 * 修改说明:  无
 * 文件版本:  V1.0
 * 文件路径:
 */
package com.hongdee.rbac.user.service.impl;

import com.hongdee.common.util.CrytpUtils;
import com.hongdee.common.util.TokenUtil;
import com.hongdee.rbac.Constant;
import com.hongdee.rbac.role.service.ITBcRoleService;
import com.hongdee.rbac.user.dao.ITBcUserDao;
import com.hongdee.rbac.user.entity.TBcRoleUser;
import com.hongdee.rbac.user.entity.TBcUser;
import com.hongdee.rbac.user.entity.TBcUserResource;
import com.hongdee.rbac.user.service.ITBcUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.hongdee.rbac.Constant.*;

/**
 * 名  称: 用户管理service层接口实现类
 * 类  型: class
 * 描  述: 用户管理service层接口实现类
 * 路  径: com.hongdee.rbac.user.service.impl
 *
 * @author: MissJin
 * 日  期: 2017/1/17/11:29
 */
@Service
public class TBcUserServiceImpl implements ITBcUserService {
    @Autowired
    private ITBcUserDao bcUserDao;
    private String tabName = "T_BC_USER";
    private List<String> deptList;
    @Autowired
    private ITBcRoleService roleService;

    /**
     * 方法名称: page
     * 方法描述: 分页查询service实现
     * 参数名称: Object object @Entity 注解标注的实体
     * 返回内容: 无
     * 异常说明: 保存异常
     * 创建用户: MissJin
     * 创建时间: 2017/1/17/11:31
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    @Override
    public Map page(String start, String limit, String oId, String name, String code, String mobile) throws Exception {


        //排除掉超级管理员角色，即 rId 为0 的角色
        String sql = "select * from " + tabName + " where " +
                "id <> '0'   " +
                "and o_id = ?";
        List params = new ArrayList();
        params.add(oId);

        //为使用索引，采用右 Like 方工
        if (!StringUtils.isEmpty(name)) {
            sql += " and u_name like ? ";
            params.add("%" + name + "%");
        }
        if (!StringUtils.isEmpty(code)) {
            sql += " and u_code like ? ";
            params.add("%" + code + "%");
        }

        if (!StringUtils.isEmpty(mobile)) {
            sql += " and u_mobile like ? ";
            params.add("%" + mobile + "%");
        }
        sql += " order by u_status desc    ";

        return this.bcUserDao.page(sql, params.toArray(), start, limit);

    }

    /**
     * 方法名称: info
     * 方法描述: 查询用户明细
     * 参数名称: id用户主键
     * 返回内容: 无
     * 异常说明: 抛出异常Exception
     * 创建用户: MissJin
     * 创建时间: 2017/1/17/16:45
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    @Override
    public Map info(String id) throws Exception {
        if (StringUtils.isEmpty(id)) {
            throw new Exception("请选择用户！");
        }
        String sql = "select * from " + tabName + " where id = ? ";
        return this.bcUserDao.info(sql, new Object[]{id});
    }


    @Override
    public List<String> role(String id, String type) throws Exception {
        if (StringUtils.isEmpty(id)) {
            throw new Exception("请选择用户！");
        }
        String sqlStr = "select r_id from t_bc_role_user where r_type= ? and u_id=?  ";
        List<Map<String, Object>> mapList = this.bcUserDao.list(sqlStr, type, id);
        List idList = new ArrayList();
        if (mapList.size() > 0) {

            for (Map map : mapList) {
                idList.add(String.valueOf(map.get("rId")));
            }
        }
        return idList;
    }

    /**
     * 方法名称: res
     * 方法描述: 查询用户资源
     * 参数名称: id用户主键
     * 返回内容: 无
     * 异常说明: 抛出异常Exception
     * 创建用户: MissJin
     * 创建时间: 2017/1/17/17:16
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    @Override
    public List<String> res(String id) throws Exception {
        String sqlStr = " select res_id from t_bc_user_resource where u_id = ? ";
        List<Map<String, Object>> resList = this.bcUserDao.list(sqlStr, id);
        List temp = new ArrayList();
        for (Map map : resList) {
            temp.add(map.get("resId"));
        }
        return temp;
    }

    /**
     * @param : id 用户主键
     * @return
     * @throws Exception 抛出异常Exception
     * @desc 更新用户状态
     */
    @Override
    public void update(String id, String status) throws Exception {
        if (StringUtils.isEmpty(id)) {
            throw new Exception("请选择用户！");
        } else if (ADMIN_USER_ID.equals(id)) {
            throw new Exception("您无权修改！");
        } else {
            String hql = "update TBcUser t set t.uStatus=:status where t.id = :id ";
            Map params = new HashMap<String, String>(1);
            params.put("status", status);
            params.put("id", id);
            this.bcUserDao.update(hql, params);
        }
    }


    /**
     * 方法名称: saveRes
     * 方法描述: 将 JSON 字符串转换为实体保存在t_user_resource或t_user_role数据库中
     * 参数名称: String  data
     * 返回内容: 保存后的实体对象
     * 异常说明:
     * 创建用户:MissJin
     * 创建时间:2017/1/17
     * 修改用户:
     * 修改时间:
     * 修改内容:
     */
    @Override
    public void saveRes(String id, String[] resIds) throws Exception {
        // 先删除
        // 后保存
        String delHQL = " delete from TBcUserResource where uId = :id ";
        Map<String, Object> params = new HashMap(10);
        params.put("id", id);
        this.bcUserDao.update(delHQL, params);
        List entityList = new ArrayList();
        TBcUserResource bcResource;
        for (String resId : resIds) {
            bcResource = new TBcUserResource();
            bcResource.setResId(resId);
            bcResource.setuId(id);
            entityList.add(bcResource);
        }
        this.bcUserDao.saveOrUpdateList(entityList);

    }

    /**
     * @param id       用户主键
     * @param password 要保存的密码
     * @return void
     * @throws Exception 基类异常
     * @desc 保存密码
     * @author zhangkai
     * @date 2017/2/10
     * @time 13:21
     * @update_user
     * @update_time
     * @update_desc:
     */
    @Override
    public void savePassWord(String id, String password) throws Exception {
        if (ADMIN_USER_ID.equals(id)) {
            throw new Exception("您无权修改！");
        }
        String hql = "update TBcUser t set t.uPassword=:uPassword where t.id = :id ";
        Map params = new HashMap(10);
        params.put("uPassword", CrytpUtils.sha1(password));
        params.put("id", id);
        this.bcUserDao.update(hql, params);
    }

    /**
     * @param user 用户实体
     * @return
     * @throws Exception 基类异常
     * @desc 保存用户实体
     * @author zhangkai
     * @date 2017/2/10
     * @time 17:20
     */
    @Override
    public void saveOrUpdate(TBcUser user) throws Exception {
        //用户登录账号需惟
        if (null == user.getId()) {
            if (existUser(user.getuCode(), user.getId(), Constant.ADD)) {
                throw new Exception("已存在相同账户！");
            }
            //密码重新加密
            user.setuPassword(CrytpUtils.sha1(user.getuPassword()));
        } else {
            //更新时
            if (ADMIN_USER_ID.equals(user.getId())) {
                throw new Exception("您无权修改此用户");
            }
            if (existUser(user.getuCode(), user.getId(), Constant.UPDATE)) {
                throw new Exception("已存在相同账户！");
            }
            Map oldUser = this.info(user.getId());
            user.setuPassword(String.valueOf(oldUser.get("uPassword")));
        }

        this.bcUserDao.saveOrUpdate(user);
    }

    /**
     * @param code
     * @param id
     * @param type
     * @return
     * @throws Exception
     * @desc 判断用户是否存在
     */
    private boolean existUser(String code, String id, int type) throws Exception {
        String sql = "select u_code from " + tabName + " where u_code = ? ";
        List param = new ArrayList();
        param.add(code);

        if (Constant.UPDATE == type) {
            sql += " and  id != ? ";
            param.add(id);
        }
        List mapList = this.bcUserDao.list(sql, param.toArray());
        return null != mapList && mapList.size() > 0;

    }

    /**
     * @param id      用户 ID
     * @param type    角色类型
     * @param roleIds 用户 ID 集合
     * @throws Exception
     * @desc 保存分配给用户的角色
     */
    @Override
    public void saveRole(String id, String type, String[] roleIds) throws Exception {
        // 先删除
        // 后保存
        String delHQL = " delete from TBcRoleUser where uId = :id and type=:type ";
        Map<String, Object> params = new HashMap(10);
        params.put("id", id);
        params.put("type", type);
        this.bcUserDao.update(delHQL, params);
        List entityList = new ArrayList();
        TBcRoleUser bcRoleUser;
        for (String roleId : roleIds) {
            bcRoleUser = new TBcRoleUser();
            bcRoleUser.setuId(id);
            bcRoleUser.setrId(roleId);
            bcRoleUser.setType(type);
            entityList.add(bcRoleUser);
        }
        this.bcUserDao.saveOrUpdateList(entityList);
    }

    /**
     * @param
     * @return Map
     * @throws Exception
     * @desc SA下拉查询
     * @author 徐钦勇
     */
    @Override
    public List<Map> combo(String companyId, String role) throws Exception {
        deptList = new ArrayList<>();
        deptList.add(companyId);
        buildDeptChild(companyId);

        String roleId = "";
        switch (role) {
            case "sa":
                roleId = SA_ROLE_ID;
                break;
            case "kf":
                roleId = KF_ROLE_ID;
                break;
            case "xb":
                roleId = XB_ROLE_ID;
                break;
            default:
                break;
        }

        String sql = " select a.id,a.u_name from " + tabName + " a left join t_bc_role_user b on a.id=b.u_id where b.r_id='" + roleId + "' and u_status = '1' ";
        if (deptList.size() > 0) {
            sql += " and a.o_id in ( ";
            for (String oid : deptList) {
                sql += " ? , ";
            }
            sql += " '' ) ";
        }
        List<Map<String, Object>> mapList = this.bcUserDao.list(sql, deptList.toArray());
        List<Map> resList = new ArrayList<Map>();
        Map temp;
        for (Map map : mapList) {
            temp = new HashMap(10);
            temp.put("label", map.get("uName"));
            temp.put("value", map.get("id"));
            resList.add(temp);
        }
        return resList;
    }

    private List<Map<String, Object>> buildDeptParent(List<Map<String, Object>> paranet) throws Exception {
        if (paranet.size() == 0) {
            return paranet;
        }
        String pId;
        for (Map<String, Object> temp : paranet) {
            pId = String.valueOf(temp.get("id"));
            List<Map<String, Object>> childList = buildDeptChild(pId);
            temp.put("child", childList);
            deptList.add(pId);
        }
        return paranet;
    }

    private List<Map<String, Object>> buildDeptChild(String opId) throws Exception {
        String sqlStr = "select * from t_bc_organ  where o_p_id = ? ";
        List<Map<String, Object>> child = this.bcUserDao.list(sqlStr, opId);
        return buildDeptParent(child);
    }

    /**
     * 公司下所有人员
     */
    @Override
    public Map allUser(String uid, String uname,String companyId, String start, String limit) throws Exception {
        StringBuffer sql = new StringBuffer();
        List<Object> params = new ArrayList<>();
        sql.append("SELECT tuser.id,tuser.u_name as uname,organ.o_name as oname,tuser.u_mobile as umobile " +
                "FROM ( " +
                "SELECT * FROM t_bc_user WHERE o_id IN ( " +
                "SELECT id FROM t_bc_organ WHERE o_p_id = ? ) ");
        if("".equals(companyId)){
            companyId=TokenUtil.getCompanyId(uid);
        }
        params.add(companyId);
        if (!"".equals(uname)) {
            sql.append(" and u_name like ? ");
            params.add("%" + uname + "%");
        }
        sql.append(")tuser " +
                "LEFT JOIN " +
                "t_bc_organ  organ ON tuser.o_id=organ.id ");
        return this.bcUserDao.page(sql.toString(), params.toArray(), start, limit);
    }

    /**
     * 公司下有任务处理权限的人员
     *
     * @author 徐钦勇
     */
    @Override
    public Map hasQxUser(String uid, String uname, String start, String limit, List<Map> data, String pcode, String code) throws Exception {
        String companyId = TokenUtil.getCompanyId(uid);
        List<Map<String, Object>> roleList = new ArrayList<>();
        if (data != null && data.size() > 0) {
            roleList = this.findRolesByTaskCode(data, companyId);
        } else {
            roleList = this.findRoleByTaskCode(pcode, code, companyId);
        }
        List<String> deptList = new ArrayList<>();
        deptList.add(companyId);
        roleService.buildDeptChild(companyId, deptList);
        StringBuffer sqlStr = new StringBuffer();
        List<String> params = new ArrayList<>();
        sqlStr.append("select t.*,o.o_name from (");
        sqlStr.append("select c.*,r.rName from t_bc_user c ," +
                "(select ru.*,GROUP_CONCAT(`name`) rName from t_bc_role_user ru,(" +

                "select ref.*,def.`name` from t_crm_task_conf ref " +
                "LEFT JOIN " +
                "t_bc_param_def def " +
                "ON " +
                "ref.task_c_code=def.`code` " +
                "where ref.task_type='1' and ref.company_id = ?" +
                ")tmep1 " +
                "where ru.r_id=tmep1.role_id group by ru.id " +
                ")r " +
//                " t_bc_role_user r " +
                "where c.id=r.u_id  ");
        params.add(companyId);
        if (roleList.size() > 0) {
            sqlStr.append("and r.r_id in (");
            for (int i = 0; i < roleList.size(); i++) {
                Map<String, Object> map = roleList.get(i);
                String roleId = String.valueOf(map.get("roleId"));
                sqlStr.append("?");
                params.add(roleId);
                if (i < (roleList.size() - 1)) {
                    sqlStr.append(",");
                }
            }
            sqlStr.append(")");
        } else {
            return new HashMap(10);
        }
        if (!"".equals(uname)) {
            sqlStr.append(" and c.u_name like ? ");
            params.add("%" + uname + "%");
        }
        sqlStr.append("and c.o_id in(");

        Map orgInfo = TokenUtil.getOrgInfo(uid);
        Map deptMap = TokenUtil.getDept(uid);
        //String oPid = (String) deptMap.get("oPId");
        boolean isStoreSa = false;
        String orgStoreId = "";
        if(deptMap != null){
            if(deptMap.get("oPId").equals("8a9aa28460026f310160059c8dd804b2")){ // 属于门店角色
                orgStoreId = (String) orgInfo.get("deptId");
                isStoreSa = true;
            }
        }

        if(!isStoreSa){ // 如果不是门店及以下权限，则都显示
            for (int i = 0; i < deptList.size(); i++) {
                String deptId = deptList.get(i);
                sqlStr.append("?");
                params.add(deptId);
                if (i < (deptList.size() - 1)) {
                    sqlStr.append(",");
                }
            }
        }
        else { // 如果是门店sa，则只显示此门店下的
            sqlStr.append("?");
            params.add(orgStoreId);
        }

        sqlStr.append(")");
        sqlStr.append("group by c.id");
        sqlStr.append(")t,t_bc_organ o where t.o_id=o.id");
        return this.bcUserDao.page(sqlStr.toString(), params.toArray(), start, limit);
    }

    @Override
    public void updateDept(String userId, String deptId) throws Exception {
        String hql = "update TBcUser set oId = :oId where id = :id ";
        Map param = new HashMap(10);
        param.put("oId", deptId);
        param.put("id", userId);
        this.bcUserDao.update(hql, param);
    }


    private List<Map<String, Object>> findRolesByTaskCode(List<Map> data, String companyId) throws Exception {
        StringBuffer sqlStr = new StringBuffer();

        sqlStr.append("select * from ( select company_id,role_id,GROUP_CONCAT(task_c_code) taskCodes from t_crm_task_conf " +
                "where  task_type='1' and company_id=? GROUP by role_id ) temp where 1=1 ");

        List<String> params = new ArrayList<>();
        params.add(companyId);
        for (int i = 0; i < data.size(); i++) {
            Map map = data.get(i);
            String taskCode = String.valueOf(map.get("typeCode"));
            sqlStr.append(" AND LOCATE(?,temp.taskCodes)>0 ");
            params.add(taskCode);
        }
        //指定人员
        return this.bcUserDao.list(sqlStr.toString(), params.toArray());
    }

    private List<Map<String, Object>> findRoleByTaskCode(String pcode, String code, String companyId) throws Exception {
        StringBuffer sqlStr = new StringBuffer();

        sqlStr.append("select * from ( select company_id,role_id,GROUP_CONCAT(task_c_code) taskCodes from t_crm_task_conf " +
                "where  task_type='1' and company_id=? GROUP by role_id ) temp where 1=1 ");
        List<String> params = new ArrayList<>();
        params.add(companyId);
        if (code != null && !"".equals(code)) {
            sqlStr.append(" AND   locate(?,temp.taskCodes)>0  ");
            params.add(code);
        } else if (!"".equals(pcode) && "".equals(code)) {
            List<String> typeCodes = new ArrayList<>();
            buildParamsChild(pcode, companyId, typeCodes);
            if (typeCodes.size() > 0) {
                for (int i = 0; i < typeCodes.size(); i++) {
                    String c = typeCodes.get(i);
                    sqlStr.append(" AND LOCATE(?,temp.taskCodes)>0 ");
                    params.add(c);
                }
            } else {
                return new ArrayList<>();
            }
        }
        return this.bcUserDao.list(sqlStr.toString(), params.toArray());
    }

    public List<Map<String, Object>> buildParamsChild(String code, String companyId, List<String> typeCodes) throws Exception {
        String sqlStr = "select def.*,pset.id setId from t_bc_param_def def " +
                "LEFT JOIN " +
                "(select * from t_bc_param_set where company_id=? )pset " +
                "ON " +
                "def.`code`=pset.`code` where def.p_code=? ";
        List<Map<String, Object>> child = this.bcUserDao.list(sqlStr, companyId, code);
        return buildDeptParent(child, typeCodes, companyId);
    }

    public List<Map<String, Object>> buildDeptParent(List<Map<String, Object>> paranet, List<String> typeCodes, String companyId) throws Exception {
        if (paranet.size() == 0) {
            return paranet;
        }
        String code;
        for (Map<String, Object> temp : paranet) {
            code = String.valueOf(temp.get("code"));
            String type = String.valueOf(temp.get("type"));
            String setId = "";
            if (temp.get("setId") != null) {
                setId = String.valueOf(temp.get("setId"));
            }
            List<Map<String, Object>> childList = buildParamsChild(code, companyId, typeCodes);
            temp.put("child", childList);
            if ("1".equals(type)) {
                if (!"".equals(setId)) {
                    String pcode = String.valueOf(temp.get("pCode"));
                    if (!typeCodes.contains(pcode)) {
                        typeCodes.add(pcode);
                    }
                }
            }
        }
        return paranet;
    }
    @Override
    public Map allusers(String uid)throws Exception{
        String sql = "SELECT id,u_name from t_bc_user where o_id <> '0'";
        List list = this.bcUserDao.list(sql);
        Map map = new HashMap();
        map.put("dataList",list);
        return map;
    }

}
